package fr.enseirb.mycub.json.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.prefs.AbstractPreferences;

import org.json.JSONException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;

import fr.enseirb.mycub.PrefManager;
import fr.enseirb.mycub.R;
import fr.enseirb.mycub.activity.AbstractPreferencesActivity;
import fr.enseirb.mycub.db.BikeDBHelper;
import fr.enseirb.mycub.db.DBAdapter;
import fr.enseirb.mycub.db.BusDBHelper;
import fr.enseirb.mycub.db.structure.LineDAO;
import fr.enseirb.mycub.db.structure.SpecificLineDAO;
import fr.enseirb.mycub.db.structure.bike.BikeStationDAO;
import fr.enseirb.mycub.db.structure.bus.BusStationDAO;
import fr.enseirb.mycub.json.JSONHandler;
import fr.enseirb.mycub.task.GetJSONAsyncTask;
import fr.enseirb.mycub.task.GetJSONMockAsyncTask;
import fr.enseirb.mycub.utils.Constants;
import fr.enseirb.mycub.utils.ParserUtils;
import fr.enseirb.mycub.utils.SeekBarPreference;
import fr.enseirb.mycub.utils.Utils;

import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.util.Log;

public class BusStationFullJSONHandler extends JSONHandler{

	public static final String STATIONS = "stations";

	public BusStationFullJSONHandler(Context context){
		super(context);
		this.preference_key_last_update_date = "BusStationJSONHandler_last_update_date";
		this.preference_key_interval_adress = "BusStationJSONHandler_interval_adress";
		this.preference_key_interval_between_update = "BusStationJSONHandler_interval_between_update";

		this.preference_key_interval_between_update_default = 60000000;
	}

	@Override
	public boolean updateLocalDatabase(String json) {
		Log.i("BusJSONFull", "update local db");
		boolean success = false;
		DBAdapter dbAdapter = DBAdapter.getInstance(context);
		try {
			//TODO MOCK
			//json = getMock();
			Gson gson = new GsonBuilder().create();
			JsonResponse dao = gson.fromJson(json, JsonResponse.class);
			Log.i("BusStationFull","json response :"+json);
			if (dao != null) {
				JsonResponseTranformed dbDAO = new JsonResponseTranformed(dao);
				Log.i("BusStationFull","transformation :"+dbDAO.toString());
				BusDBHelper.cleanAndInsertBusLines(dbAdapter.getDB(), dbDAO.lines);
				BusDBHelper.cleanAndInsertBusSpecificLines(dbAdapter.getDB(), dbDAO.specificLines);
				BusDBHelper.cleanAndInsertBusStations(dbAdapter.getDB(), dbDAO.stationsDAO);
				success = true;
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return success;
	}

	@Override
	protected void standardUpdate() {
		String baseAddress = Constants.LOCAL_SERVER_URL+"/bus/";
		String address = baseAddress+44+"/"+0+"/"+1000000000;
		if(PrefManager.mgr.getBoolean(
				AbstractPreferencesActivity.ENABLE_DISTANCE_FILTER,
				false) && longitude != 1337 && latitude != 1337){
			int radius = PrefManager.mgr.getInt(AbstractPreferencesActivity.DISTANCE_FILTER,
					SeekBarPreference.DEFAULT_DISTANCE);
			address = baseAddress+longitude+"/"+latitude+"/"+radius;
			
		}
		Log.i("JSON Handler", address);
		new GetJSONAsyncTask(this, address).execute();
	}

	public String getMock(){
		try {
			return	ParserUtils.getString(context.getResources().openRawResource(R.raw.bus));
		} catch (NotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private class JsonResponse{
		ArrayList<BusStationJsonDAO> stations;
	}


	private class JsonResponseTranformed{
		ArrayList<BusStationDAO> stationsDAO;
		ArrayList<SpecificLineDAO> specificLines;
		ArrayList<LineDAO> lines;

		public JsonResponseTranformed(JsonResponse dao){
			//extraction des lignes
			Set<String> lines = new HashSet<String>();
			int size = dao.stations.size();
			for(int i = 0; i < size; i++)
				lines.addAll(Arrays.asList(dao.stations.get(i).specificLineId.split("\\s*/\\s*")));

			Log.i("JSON HANDLER", "lignes trouvées : "+lines.size());
			//on crée les lignes :
			LineDAO temp = null;
			size = lines.size();
			Object[] linesTab = lines.toArray();
			this.lines = new ArrayList<LineDAO>();

			for(int i = 0; i < size; i++ ){
				temp = new LineDAO();
				temp.setId(i);
				temp.setName((String)linesTab[i]);
				temp.setType(LineDAO.BUS);
				this.lines.add(temp);
			}

			//création des specific lines
			SpecificLineDAO temp2 = null;
			this.specificLines = new ArrayList<SpecificLineDAO>();
			for(int i = 0; i < size; i++ ){
				temp2 = new SpecificLineDAO();
				temp2.setId(i);
				temp2.setName((String)linesTab[i]);
				temp2.setLineId(i);
				this.specificLines.add(temp2);
			}

			stationsDAO = BusStationJsonDAO.getDAOList(dao.stations, specificLines);

		}

		@Override
		public String toString() {
			return "JsonResponseTranformed [" 
					+ ", specificLines=" + specificLines + ", lines=" + lines
					+  "stationsDAO="+ stationsDAO+"]";
		}


	}

	static class BusStationJsonDAO{
		@SerializedName("line")
		private String specificLineId;
		@SerializedName(ID)
		protected int mId;
		@SerializedName(NAME)
		protected String mName;
		ArrayList<Double> location;
		private String address;
		protected boolean mIsFavorite;

		public static final String ID = "id";
		public static final String NAME = "name";
		public static final String OPEN = "open";	
		public static final String LATITUDE = "latitude";
		public static final String LONGITUDE = "longitude";

		public BusStationDAO getDAO( ArrayList<SpecificLineDAO> specificLines){
			BusStationDAO station = new BusStationDAO();
			station.setId(mId);
			station.setmLatitude(location.get(1));
			station.setmLongitude(location.get(0));
			station.setName(mName);
			//gestion du statut pas encore active
			station.setOpen(true);
			station.setAddress(getAddress());
			List<String> items = Arrays.asList(specificLineId.split("\\s*/\\s*"));
			try {
				int[] ids = new int[items.size()];
				for(int i = 0; i < items.size(); i++){
					for(int j = 0; j < specificLines.size(); j++){
						if(items.get(i).equals(specificLines.get(j).getName())){
							ids[i] = specificLines.get(j).getId();
						}
					}
				}

				station.setSpecificLineId(ids);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return station;
		}

		public static ArrayList<BusStationDAO> getDAOList(ArrayList<BusStationJsonDAO> list, ArrayList<SpecificLineDAO> specificLines){
			ArrayList<BusStationDAO> finalList = new ArrayList<BusStationDAO>();
			int size = list.size();
			for(int i = 0; i < size; i++){
				finalList.add(list.get(i).getDAO(specificLines));
			}
			return finalList;
		}

		public String getName() {
			return mName;
		}

		public void setName(String name) {
			mName = name;
		}

		public void setId(int id) {
			this.mId = id;
		}

		public int getId() {
			return this.mId;
		}

		public boolean isFavorite() {
			return mIsFavorite;
		}

		public void setFavorite(boolean isFavorite) {
			mIsFavorite = isFavorite;
		}

		public String getAddress() {
			return address;
		}

		public void setAddress(String address) {
			this.address = address;
		}



	}

}
